<?php
/**
 * Created by PhpStorm.
 * User: v_jingzhili
 * Date: 2019/4/7
 * Time: 9:25
 */

namespace Lib\Service;

use Lib;
use Model;

/**
 * 根据类型处理json数据
 * 支持类型 1：根据json文件处理入库初始数据；2：根据最近版本号 做数据对比
 * Class JsonService
 * @package Lib\Service
 */
class JsonService
{
    const CATE_TMOBA_CHAMPION = 1;//英雄 tmoba
    const CATE_JSON_CHAMPION = 2;//英雄 json
    const CATE_TMOBA_CHAMPION_SKINS = 3;//皮肤 从英雄的tmoba 获取皮肤数据
    const CATE_TMOBA_SKINS = 4;//皮肤 tmoba
    const CATE_TMOBA_ITEM = 5;//道具 tmoba
    const CATE_JSON_ITEM = 6;//道具 json
    const CATE_TMOBA_SPELL = 7;//技能 tmoba
    const CATE_JSON_SPELL = 8;//技能 json

    const TYPE_FILE = 1;//文件处理数据 必须传path参数
    const TYPE_DB = 2;//根据数据库比较最近三个版本 传版本号id与该版本号对比 不传版本号将获取当前版本号id

    //db 数据对比
    const DB_TYPE_CHAMPION = 1;//英雄
    const DB_TYPE_ITEM = 2;//道具
    const DB_TYPE_SKINS = 3;//皮肤
    const DB_TYPE_SPELL = 4;//技能

    private $path;
    private $json;
    private $type;
    private $version_id;
    private $dataType;
    private $db_type;


    //皮肤路径 start
    //英雄页主图
    private $skinMainImg = "https://game.gtimg.cn/images/lol/act/img/skin/";//+ big + 皮肤id + .jpg
    //英雄页头像
    private $skinIconImg = "https://game.gtimg.cn/images/lol/act/img/skin/";//+ small + 皮肤id + .jpg
    //loading图
    private $skinLoadingImg = "https://game.gtimg.cn/images/lol/act/img/appskin/";// + 皮肤id + .jpg
    //视频封面
    private $skinVideoImg = "https://game.gtimg.cn/images/lol/act/img/skinvideo/";//+ sp + 皮肤id + .jpg
    //攻略中心头像
    private $skinSourceImg = "https://game.gtimg.cn/images/lol/act/img/guidetop/";//+ guide + 皮肤id + .jpg
    //皮肤路径 end

    //道具路径 start
    //道具图片路径
    //private $itemIconPath = "https://game.gtimg.cn/images/lol/img/item/";//+ 道具id + .png
    private $itemIconPath = "https://game.gtimg.cn/images/lol/act/img/item/";//+ j道具id + .png
    //道具路径 end

    //英雄技能 start
    //英雄技能图片路径
    //private $spellAbilityIconPath = "https://game.gtimg.cn/images/lol/img/spell/";//+ 英雄英文名 + 大写技能快捷键 + .png
    private $spellAbilityIconPath = "https://game.gtimg.cn/images/lol/act/img/spell/";//+ 英雄英文名 + 大写技能快捷键 + .png
    //英雄被动技能图片路径
    //private $spellPassiveIconPath = "https://game.gtimg.cn/images/lol/img/passive/";//+ 英雄英文名 + Passive.png
    private $spellPassiveIconPath = "https://game.gtimg.cn/images/lol/act/img/passive/";//+ json文档中路径+abilityIconPath的最后一段文件名
    //英雄技能 end


    /**
     * 设置json数据与数据表对应关系
     * @var array
     */
    private $category = array(
        //英雄 tmoba => 英雄表
        '1' => array(
            'id' => 'heroId',
            'name' => 'name',
            'alias' => 'alias',
            'title' => 'title',
            'roles' => 'roles',//array serialize()
            'shortBio' => 'shortBio',
            'tacticalInfo' => array(
                 'style' => 'style',
                 'difficulty' => 'difficultyL',
                 'damageType' => 'damageType',
            ),
            'playstyleInfo' => array(
                 'damage' => 'damage',
                 'durability' => 'durability',
                 'crowdControl' => 'crowdControl',
                 'mobility' => 'mobility',
                 'utility' => 'utility',
            ),
        ),
        //英雄 json => 英雄表
        '2' => array(
            'key' => 'heroId',
            'allytips' => 'allytips',
            'enemytips' => 'enemytips',
            'image' => 'image',
            'info' => array(
                'attack' => 'attack',
                'defense' => 'defense',
                'magic' => 'magic',
                'difficulty' => 'difficulty',
            ),
            'stats' => array(
                'hp' => 'hp',
                'hpperlevel' => 'hpperlevel',
                'mp' => 'mp',
                'mpperlevel' => 'mpperlevel',
                'movespeed' => 'movespeed',
                'armor' => 'armor',
                'armorperlevel' => 'armorperlevel',
                'spellblock' => 'spellblock',
                'spellblockperlevel' => 'spellblockperlevel',
                'attackrange' => 'attackrange',
                'hpregen' => 'hpregen',
                'hpregenperlevel' => 'hpregenperlevel',
                'mpregen' => 'mpregen',
                'mpregenperlevel' => 'mpregenperlevel',
                'crit' => 'crit',
                'critperlevel' => 'critperlevel',
                'attackdamage' => 'attackdamage',
                'attackdamageperlevel' => 'attackdamageperlevel',
                'attackspeedperlevel' => 'attackspeedperlevel',
                'attackspeed' => 'attackspeed',
            )
        ),
        //英雄 tmoba => 皮肤表
        '3' => array(
            //英雄json 获取数据
            'id' => 'heroId',
            'name' => 'heroName',
            'title' => 'heroTitle',
            'skins' => array(
                'id' => 'skinId',
                'name' => 'name',
            ),// array 遍历

        ),
        //皮肤 tmoba => 皮肤表
        '4' => array(
            'id' => 'skinId',
            'name' => 'name',
            'isBase' => 'isBase',
            'emblems' => array(
                'name' => 'emblemsName',
            ),
            'chromas' => array(
                'id' => 'skinId',
                'name' => 'name',
                //chromasBelongId 炫彩皮肤从属 炫彩皮肤有这个id

            ),//array 循环遍历添加 炫彩皮肤 chromasBelongId 为 母皮肤id
            'description' => 'description'

        ),
        //道具 tmoba => 道具表
        '5' => array(
            'id' => 'itemId',//道具id
            'name' => 'name',
            'iconPath' => 'iconPath',
            'price' => 'price',
            'description' => 'description',
            'mapStringIdInclusions' => 'maps',//array serialize()
            'categories' => 'types',//array serialize()
        ),
        //道具 json => 道具表
        '6' => array(
            //道具id => 遍历 data 的 key 记录为 itemId
            'plaintext' => 'plaintext',
            'into' => 'into',//array serialize()
            'from' => 'from',//部分数据没有这个字段 array serialize()
            'gold' => array(
                'total' => 'total',
                'sell' => 'sell',
            ),

        ),
        //英雄tmoba => 技能表
        '7' => array(
            //英雄tmoba 获取数据
            'id' => 'heroId',
            'passive' => array(
                'name' => 'name',
                'abilityIconPath' => 'abilityIconPath',
                'abilityVideoPath' => 'abilityVideoPath',
                'description' => 'description',
                'spellKey' => 'spellKey',//被动技能 spellKey 的值为 passive
            ),
            'spells' => array(
                'name' => 'name',
                'abilityIconPath' => 'abilityIconPath',
                'abilityVideoPath' => 'abilityVideoPath',
                'spellKey' => 'spellKey',
                'description' => 'description',
                'dynamicDescription' => 'dynamicDescription',
            ),//array 根据spellKey 遍历； spellKey:q w e r

        ),
        //英雄json => 技能表
        '8' => array(
            //英雄json 获取数据
            'key' => 'heroId',
            'spells' => array(
                //'id' => 'spellKey',//格式 英雄英文名+大写操作快捷键 保存数据时取最后一个字符串 并转成小写字母
                'name' => 'name',
                'cost' => 'cost', //array serialize()
                'costBurn' => 'costburn',
                'cooldown' => 'cooldown', //array serialize()
                'cooldownBurn' => 'cooldownburn',
            ),//array

        ),
    );

    /**
     * 版本比较是需要传的参数 用于查找数据/sql where条件
     * @var array
     */
    private $db_parm = array(
        //英雄
        '1' => array(
            'heroId'
        ),
        //道具
        '2' => array(
            'itemId'
        ),
        //皮肤
        '3' => array(
            'skinId'
        ),
        //技能
        '4' => array(
            'heroId',
            'spellKey',
        ),
    );
    /**
     * 数据对比时不需要对比的字段
     * @var array
     */
    private $noCompareKey = array(
        'id',
        'heroId',
        'spellKey',
        'skinId',
        'itemId',
        'versionId',
        'isDelete',
        'creater',
        'createTime',
        'updateMan',
        'updateTime',
        'versionNumber',
        'releasestatus',
        'skinIsUpdate',
        'isUpdate',
        'heroName',
        'heroTitle',
    );

    /**
     * DiffService constructor.
     * @param $type 处理类型 1：文件处理数据 （必须存path参数）2：根据数据库比较最近三个版本
     * @param $path json 文件路径/文件名称
     * @param $version_id 版本号id 要比较的版本id 不传将获取当前版本
     * @param $db_type 要比较的数据类型 1：英雄 2：道具 3：皮肤 4：技能
     * @param $parm 要比较数据类型是查找数据的必要条件 详情查看 $db_parm
     */
    public function __construct($type = self::TYPE_FILE, $path = '', $version_id = null, $db_type = null, $parm = array())
    {
        switch (intval($type)) {
            case self::TYPE_FILE:
                if (empty($path)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",path 参数不能为空");
                    $res['code'] = 404;
                    $res['msg'] = 'path 参数不能为空';
                    return $res;
                };
                if (!file_exists($path)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",{$path} 文件不存在");
                    $res['code'] = 404;
                    $res['msg'] = "{$path} 文件不存在";
                    return $res;
                };
                $this->path = $path;
                $json = file_get_contents($path);
                recordAMSLog(__FILE__ . "," . __LINE__ . ",file_get_contents:".var_export($json,true));
                $this->json = json_decode($json, true);

                recordAMSLog(__FILE__ . "," . __LINE__ . ",json:".var_export($this->json,true));
                if (!is_array($this->json)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",{$path} 文件数据不符合要求，请核对再上传");
                    $res['code'] = 404;
                    $res['msg'] = "{$path} 文件数据不符合要求，请核对再上传";
                    return $res;
                }
                $typeData = $this->checkJson();
                if ($typeData['type'] === 0) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",{$path} 文件暂不支持");
                    $res['code'] = 404;
                    $res['msg'] = "{$path} json 文件暂不支持";
                    return $res;
                }
                $this->dataType = $typeData['type'];
                break;
            case self::TYPE_DB:
                //获取最近三个版本的数据
                if(empty($db_type)){
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",db_type 参数不能为空");
                    $res['code'] = 404;
                    $res['msg'] = 'db_type 参数不能为空';
                    return $res;
                }
                $this->db_type = $db_type;
                if(empty($parm)){
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",parm 参数不能为空");
                    $res['code'] = 404;
                    $res['msg'] = 'parm 参数不能为空';
                    return $res;
                }
                $typeData = $this->checkDb($parm);
                if ($typeData['code'] === 404) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",".$typeData['msg']);
                    $res['code'] = 404;
                    $res['msg'] = $typeData['msg'];
                    return $res;
                }elseif ($typeData['code'] === 200){
                    //空数据
                    $res['code'] = 200;
                    $res['msg'] = "无数据，请检查parm参数";
                    return $res;
                }else{
                    $this->json = $typeData['data'];
                }
                break;
            default:
                recordAMSLog(__FILE__ . "," . __LINE__ . ",文件暂不支持");
                $res['code'] = 404;
                $res['msg'] = "文件暂不支持";
                return $res;
                break;
        }
        $this->type = $type;
        if (empty($version_id)) {
            $db = Lib\Db\DbModel::init();
            $where['isCurrent'] = 1;
            $version = $db->table('tbversion')->where($where)->order('id')->find();
            if (empty($version)) {
                recordAMSLog(__FILE__ . "," . __LINE__ . ",请先创建一个版本");
                $res['code'] = 404;
                $res['msg'] = "请先创建一个当前版本";
                return $res;
            }
            $version_id = $version['id'];
        }
        $this->version_id = $version_id;

    }

    /**
     * @param string $json
     * @return mixed
     */
    public function checkJson($json = '')
    {
        if ($this->type == self::TYPE_DB) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",db类型不需要检测文件类型");
            $res['code'] = 404;
            $res['msg'] = "db类型不需要检测文件类型";
            return $res;
        }
        if (empty($json)) {
            $json = $this->json;
        }
        if (empty($json)) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",json文件内容为空，请检测数据源");
            $res['code'] = 404;
            $res['msg'] = "json文件内容为空，请检测数据源";
            return $res;
        }
        $res['code'] = 0;
        $db = Lib\Db\DbModel::init();
        $find = $db->table('tbconfig')->where(['alias' => 'checkJson'])->find('value');
        $checkJson = json_decode($find['value'], true);
        if (empty($checkJson)) {
            //英雄 tmoba
            if (array_key_exists('alias', $json) && array_key_exists('name', $json) && array_key_exists('id',
                    $json) && array_key_exists('skins', $json) && array_key_exists('spells', $json)) {
                $res['type'] = self::CATE_TMOBA_CHAMPION;
                $res['msg'] = '英雄tmoba数据';
                return $res;
            }

            //英雄 json
            if ($json['type'] == 'champion' && $json['format'] == 'standAloneComplex') {
                $res['type'] = self::CATE_JSON_CHAMPION;
                $res['msg'] = '英雄json数据';
                return $res;
            }
            //道具 tmoba
            if (count($json) > 1) {
                foreach ($json as $k => $v) {
                    if (array_key_exists('categories', $v) && array_key_exists('mapStringIdInclusions', $v)) {
                        $res['type'] = self::CATE_TMOBA_ITEM;
                        $res['msg'] = '道具tmoba数据';
                        return $res;
                    }
                }
            }
            //道具 json
            if ($json['type'] == 'item') {
                $res['type'] = self::CATE_JSON_ITEM;
                $res['msg'] = '道具json数据';
                return $res;
            }
            //皮肤 tmoba
            if (count($json) > 1) {
                foreach ($json as $k => $v) {
                    if (array_key_exists('emblems', $v) && array_key_exists('skinType', $v)) {
                        $res['type'] = self::CATE_TMOBA_SKINS;
                        $res['msg'] = '皮肤tmoba数据';
                        return $res;
                    }
                }
            }
            $res['type'] = 0;
            $res['msg'] = '文件暂不支持';
            return $res;
        }

        foreach ($checkJson as $k => $v) {
            switch ($k) {
                case self::CATE_TMOBA_CHAMPION:
                    $res['type'] = self::CATE_TMOBA_CHAMPION;
                    $res['msg'] = '英雄tmoba数据';
                    break;
                case self::CATE_JSON_CHAMPION:
                    $res['type'] = self::CATE_JSON_CHAMPION;
                    $res['msg'] = '英雄json数据';
                    break;
                case self::CATE_TMOBA_ITEM:
                    $res['type'] = self::CATE_TMOBA_ITEM;
                    $res['msg'] = '道具tmoba数据';
                    break;
                case self::CATE_JSON_ITEM:
                    $res['type'] = self::CATE_JSON_ITEM;
                    $res['msg'] = '道具json数据';
                    break;
                case self::CATE_TMOBA_SKINS:
                    $res['type'] = self::CATE_TMOBA_SKINS;
                    $res['msg'] = '皮肤tmoba数据';
                    break;
                default:
                    $res['type'] = 0;
                    $res['msg'] = '文件暂不支持';
                    break;
            }
            //检测key是否存在
            if ($v['type'] == 1) {
                //key在第一维度
                $flag = 0;
                foreach ($v['data'] as $key => $value) {
                    if (!array_key_exists($value, $json)) {
                        $flag = 1;
                    }
                }
                if ($flag === 0) {
                    return $res;
                }
                //key在第二维度
                $flag = 0;
                if (count($json) > 1) {
                    $i = 1;
                    foreach ($json as $k1 => $v1) {
                        if ($i > 1) {
                            break;
                        }
                        if ($i == 1) {
                            foreach ($v['data'] as $key => $value) {
                                if (!array_key_exists($value, $v1)) {
                                    $flag = 1;
                                }
                            }
                        }
                        $i++;
                    }
                }
                if ($flag === 0) {
                    return $res;
                }
            }
            //检测key=value
            if ($v['type'] == 2) {
                $flag = 0;
                foreach ($v['data'] as $key => $value) {
                    if ($json[$key] != $value) {
                        $flag = 1;
                    }
                }
                if ($flag === 0) {
                    return $res;
                }
            }
        }
        $res['type'] = 0;
        $res['msg'] = '文件暂不支持';
        return $res;
    }

    /**
     * @param array $parm 查询参数
     * @return mixed
     */
    public function checkDb($parm)
    {
        if ($this->type == self::TYPE_FILE) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",file类型不支持比较最近三个版本");
            $res['code'] = 404;
            $res['msg'] = "file类型不支持比较最近三个版本";
            return $res;
        }
        $res['code'] = 0;
        $db_type = $this->db_type;
        $checkParm = $this->db_parm[$db_type];
        if(empty($checkParm)){
            $res['code'] = 404;
            $res['msg'] = "db_type:".$db_type.",暂不支持";
            return $res;
        }
        foreach ($checkParm as $value){
            if(empty($parm[$value])){
                recordAMSLog(__FILE__ . "," . __LINE__ . ",parm_key:".$value.",不能为空");
                $res['code'] = 404;
                $res['msg'] = "parm_key:".$value.",不能为空";
                return $res;
            }
            $where[$value] = $parm[$value];
        }
        //当前版本id
        $model = new Model\VersionModel();
        $versionId = $model->getCurrentVersion()['id'];
        $where['versionId'] = array('!=',$versionId);
        switch (intval($db_type)){
            case self::DB_TYPE_CHAMPION:
                $table = "tbhero";
                $res['msg'] = 'tbhero数据';
                //英雄
                break;
            case self::DB_TYPE_ITEM:
                $table = "tbitems";
                $res['msg'] = 'tbitems数据';
                //道具
                break;
            case self::DB_TYPE_SKINS:
                $table = "tbskins";
                $res['msg'] = 'tbskins数据';
                //皮肤
                break;
            case self::DB_TYPE_SPELL:
                $table = "tbspells";
                $res['msg'] = 'tbspells数据';
                //技能
                break;
            default:
                recordAMSLog(__FILE__ . "," . __LINE__ . ",db_type:".$db_type.",暂不支持");
                $res['code'] = 404;
                $res['msg'] = "db_type:".$db_type.",暂不支持";
                return $res;
                break;
        }
        $db = Lib\Db\DbModel::init();
        $data = $db->table($table)->where($where)->order('versionId')->find();
        if(empty($data)){
            $res['code'] = 200;
            $res['error'] = '数据为空';
            return $res;
        }
        $res['code'] = 0;
        $res['data'] = $data;
        return $res;
    }

    /**
     * 返回json文件与当前在线版本 存在差异的个数
     * @param null $version_id 版本id
     * @return mixed
     */
    public function getChangeNumByFile($version_id = null)
    {
        //获取json文件的数据
        $file_json = $this->getDataByFile();
        //获取要对比的版本数据
        if (empty($version_id)) {
            $version_id = $this->version_id;
        }
        $db = Lib\Db\DbModel::init();

        $dataType = $this->dataType;

        //获取文件信息
//        $path = $this->path;
//        $res['size'] = format_bytes(filesize($path));
//        $res['filename'] = basename($path);
        switch ($dataType) {
            case self::CATE_TMOBA_CHAMPION:
            case self::CATE_JSON_CHAMPION:
                //比较英雄
                $i = 0;
                $where['versionId'] = $version_id;
                $where['heroId'] = $file_json['data']['heroId'];
                $hero = $db->table('tbhero')->where($where)->order('id')->find();
                if (empty($hero)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",该版本还没有英雄数据");
                    $res['code'] = 0;
                    $res['msg'] = "该版本还没有英雄数据";
                    $res['change_msg'] = "";
                    $res['change_count'] = 0;
                    $res['spells_count'] = 0;
                    return $res;
                }
                foreach ($file_json['data'] as $k => $v) {
                    //检测英雄参数有多少个变化
                    foreach ($hero as $k1 => $v1) {
                        //key 相同比较值
                        if ($k == $k1 && $v != $this->removeStripslashes($v1)) {
                            $i += 1;
                            break;
                        }
                    }
                }
                $heroChange = 0;
                if ($i > 0) {
                    $heroChange = 1;
                }
                $res['code'] = 0;
                $res['msg'] = "英雄数据";
                $res['change_count'] = $i;
                $res['spells_count'] = 0;
                //比较技能
                $spells = $db->table('tbspells')->where($where)->order('id')->select();
                if (empty($spells)) {
                    if ($heroChange === 1) {
                        $res['change_msg'] = "1个英雄";
                    } else {
                        $res['change_msg'] = "";
                    }
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",该版本还没技能数据");
                    return $res;
                }
                $spells = $this->updateDataKey($spells, self::CATE_TMOBA_SPELL);
                $file_json['spells'] = $this->updateDataKey($file_json['spells'], self::CATE_TMOBA_SPELL);
                $j = 0;
                foreach ($file_json['spells'] as $k => $v) {
                    if (!empty($spells[$k])) {
                        $z = 0;
                        foreach ($v as $k1 => $v1) {
                            foreach ($spells[$k] as $k2 => $v2) {
                                //key 相同比较值
                                if ($k1 == $k2 && $v1 != $this->removeStripslashes($v2)) {
                                    $z += 1;
                                    break;
                                }
                            }
                            if($z >0){
                                break;
                            }
                        }
                        if($z >0){
                            $j += 1;
                            continue;
                        }

                    }

                }
                $res['spells_count'] = $j;
                if($heroChange === 1){
                    if($j === 0){
                        $res['change_msg'] = "1个英雄";
                    }else{
                        $res['change_msg'] = "1个英雄 ".$j."个技能";
                    }
                }else{
                    if($j === 0){
                        $res['change_msg'] = "";
                    }else{
                        $res['change_msg'] = $j."个技能";
                    }
                }

                return $res;
                break;
            case self::CATE_TMOBA_SKINS:
                //比较皮肤
                $i = 0;
                $where['versionId'] = $version_id;
                $file_json['data'] = $this->updateDataKey($file_json['data'], self::CATE_TMOBA_SKINS);
                $skins = $db->table('tbskins')->where($where)->order('skinId', 'asc')->select();
                if (empty($skins)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",该版本还没有皮肤数据");
                    $res['code'] = 0;
                    $res['msg'] = "该版本还没有皮肤数据";
                    $res['change_msg'] = "";
                    $res['change_count'] = 0;
                    $res['spells_count'] = 0;
                    return $res;
                }
                $skins = $this->updateDataKey($skins, self::CATE_TMOBA_SKINS);
                foreach ($file_json['data'] as $k => $v) {
                    if (!empty($skins[$k])) {
                        foreach ($v as $k1 => $v1) {
                            foreach ($skins[$k] as $k2 => $v2) {
                                //key 相同比较值
                                if ($k1 == $k2 && $v1 != $this->removeStripslashes($v2)) {
                                    $i += 1;
                                }
                            }
                        }
                    }
                }
                $res['code'] = 0;
                $res['msg'] = "皮肤tmoba数据";
                $res['change_count'] = $i;
                //比较炫彩皮肤
                $j = 0;
                $file_json['chromas'] = $this->updateDataKey($file_json['chromas'], self::CATE_TMOBA_SKINS);
                foreach ($file_json['chromas'] as $k => $v) {
                    if (!empty($skins[$k])) {
                        foreach ($v as $k1 => $v1) {
                            foreach ($skins[$k] as $k2 => $v2) {
                                //炫彩皮肤字段处理 这几个字段导入数据库的时候才写入 tmoba 数据中为空 不需要比较
                                if(in_array($k1,['heroId','heroName','heroTitle','loadingImg'])){
                                    continue;
                                }
                                //key 相同比较值
                                if ($k1 == $k2 && $v1 != $this->removeStripslashes($v2)) {
                                    $j += 1;
                                }
                            }
                        }
                    }
                }
                $res['chromas_count'] = $j;
                if($i === 0 && $j === 0){
                    $res['change_msg'] = "";
                }else{
                    $res['change_msg'] = $i."个皮肤 ".$j."个炫彩";
                }
                return $res;
                break;
            case self::CATE_TMOBA_ITEM:
            case self::CATE_JSON_ITEM:
                //比较道具
                //tbitems
                $i = 0;
                $where['versionId'] = $version_id;
                $file_json['data'] = $this->updateDataKey($file_json['data'], self::CATE_TMOBA_ITEM);
                $item = $db->table('tbitems')->where($where)->order('itemId', 'asc')->select();
                if (empty($item)) {
                    recordAMSLog(__FILE__ . "," . __LINE__ . ",该版本还没有道具数据");
                    $res['code'] = 0;
                    $res['msg'] = "该版本还没有道具数据";
                    $res['change_msg'] = "";
                    $res['change_count'] = 0;
                    $res['spells_count'] = 0;
                    return $res;
                }
                $item = $this->updateDataKey($item, self::CATE_TMOBA_ITEM);
                foreach ($file_json['data'] as $k => $v) {
                    if (!empty($item[$k])) {
                        foreach ($v as $k1 => $v1) {
                            foreach ($item[$k] as $k2 => $v2) {
                                //key 相同比较值
                                if ($k1 == $k2 && $v1 != $this->removeStripslashes($v2)) {
                                    $i += 1;
                                }
                            }
                        }
                    }
                }
                $res['code'] = 0;
                $res['msg'] = "道具数据";
                $res['change_count'] = $i;
                if($i === 0){
                    $res['change_msg'] = "";
                }else{
                    $res['change_msg'] = $i."个道具";
                }
                return $res;
                break;
            default:
                recordAMSLog(__FILE__ . "," . __LINE__ . ",暂不支持的比较类型");
                $res['code'] = 404;
                $res['msg'] = "暂不支持的比较类型";
                $res['change_msg'] = "暂不支持的比较类型";
                return $res;
                break;
        }
    }

    /**
     * 通过json文件 返回 处理后的入库数据
     * @return mixed
     */
    public function getDataByFile()
    {
        if ($this->type != self::TYPE_FILE) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",该方法仅用于获取json文件的数据");
            $res['code'] = 404;
            $res['msg'] = "该方法仅用于获取json文件的数据";
            return $res;
        }
        $json = $this->json;
        $type = $this->dataType;
        $category = $this->category[$type];
        $data['code'] = 0;
        $data['type'] = $type;
        $data['data'] = array();
        switch ($type) {
            case self::CATE_TMOBA_CHAMPION:
                //返回英雄数据及皮肤数据及技能数据
                $data['msg'] = '返回 英雄tmoba数据data、皮肤数据skins、技能数据spells';
                //组装基础数据
                $hero = array();
                foreach ($category as $k => $v) {
                    if (is_array($v)) {
                        foreach ($v as $k1 => $v1) {
                            $hero[$v1] = importFilter($json[$k][$k1]);
                        }
                    } else {
                        $hero[$v] = importFilter($json[$k]);
                    }
                }
                $data['data'] = $hero;
                //获取皮肤分类key
                $skinsCate = $this->category[self::CATE_TMOBA_CHAMPION_SKINS];
                $data['skins'] = array();//皮肤
                $skins = array();
                $skins_key = array();
                //组装皮肤数据
                foreach ($skinsCate as $k => $v) {
                    if (!is_array($v)) {
                        $skins[$v] = importFilter($json[$k]);
                    } else {
                        $skins_key[$k] = $v;
                    }
                }
                //循环英雄表的皮肤数据 封装皮肤数据
                foreach ($skins_key as $k => $v) {
                    foreach ($json[$k] as $k1 => $v1) {
                        foreach ($v as $k2 => $v2) {
                            $skins[$v2] = importFilter($v1[$k2]);
                        }
                        //过滤不符合的数据
                        if(!empty($skins['skinId'])){
                            $data['skins'][] = $skins;
                        }
                    }
                }
                unset($skins);
                unset($skins_key);
                unset($skinsCate);

                //获取技能分类key
                $spellsCate = $this->category[self::CATE_TMOBA_SPELL];
                $data['spells'] = array();//技能
                $spells = array();
                $spells_key = array();
                //组装技能数据
                foreach ($spellsCate as $k => $v) {
                    if (!is_array($v)) {
                        $spells[$v] = importFilter($json[$k]);
                    } else {
                        $spells_key[$k] = $v;
                    }
                }
                foreach ($spells_key as $k => $v) {
                    if ($k == 'passive') {
                        //被动技能 一维数组
                        foreach ($v as $k1 => $v1) {
                            $spells[$v1] = importFilter($json[$k][$k1]);
                            if ($k1 == 'spellKey') {
                                $spells[$v1] = 'passive';
                            }
                        }
                        //技能图标处理
                        //$spells['abilityIconPath'] = $this->spellPassiveIconPath.$hero['alias'].'Passive.png';
                        $spells['abilityIconPath'] = $this->spellPassiveIconPath.basename($spells['abilityIconPath']);
                        $data['spells'][] = $spells;

                    } else {
                        foreach ($json[$k] as $k1 => $v1) {
                            foreach ($v as $k2 => $v2) {
                                $spells[$v2] = importFilter($v1[$k2]);
                            }
                            //技能图标处理
                            $spells['abilityIconPath'] = $this->spellAbilityIconPath.$hero['alias'].strtoupper($spells['spellKey']).'.png';
                            //$spells['abilityIconPath'] = $this->spellAbilityIconPath.basename($spells['abilityIconPath']);
                            $data['spells'][] = $spells;
                        }
                    }

                }
                unset($spellsCate);
                unset($spells);
                unset($spells_key);
                break;
            case self::CATE_JSON_CHAMPION:
                //返回英雄数据 及 技能数组
                $data['msg'] = '英雄json数据data、技能数据spells';
                foreach ($json['data'] as $k => $v) {
                    $json = $v;
                }

                $hero = array();
                foreach ($category as $k => $v) {
                    if (is_array($v)) {
                        foreach ($v as $k1 => $v1) {
                            $hero[$v1] = importFilter($json[$k][$k1]);
                        }
                    } else {
                        //处理使用技巧
                        if($k == 'allytips'){
                            $str = "";
                            foreach ($json[$k] as $vj){
                                if($str == ""){
                                    $str .= $vj;
                                }else{
                                    $str .= "\n".$vj;
                                }
                            }
                            $hero[$v] = importFilter($str);
                        }elseif($k == 'enemytips'){
                            //处理被动技巧
                            $str = "";
                            foreach ($json[$k] as $vj){
                                if($str == ""){
                                    $str .= $vj;
                                }else{
                                    $str .= "\n".$vj;
                                }
                            }
                            $hero[$v] = importFilter($str);
                        }else{
                            $hero[$v] = importFilter($json[$k]);
                        }
                    }
                }
                $data['data'] = $hero;

                //获取技能分类key
                $spellsCate = $this->category[self::CATE_JSON_SPELL];
                $data['spells'] = array();//技能
                $spells = array();
                $spells_key = array();
                //组装技能数据
                foreach ($spellsCate as $k => $v) {
                    if (!is_array($v)) {
                        $spells[$v] = importFilter($json[$k]);
                    } else {
                        $spells_key[$k] = $v;
                    }
                }
                foreach ($spells_key as $k => $v) {
                    foreach ($json[$k] as $k1 => $v1) {
                        foreach ($v as $k2 => $v2) {
                            /*if ($k2 == 'id') {
                                //$spells[$v2] = strtolower(substr($v1[$k2], -1));//json 数据的技能名称需要特殊处理
                                if(!in_array($spells['spellKey'],array('w','q','e','r'))){
                                    $spells[$v2] = $v1[$k2];//json 数据的技能名称需要特殊处理
                                }else{
                                    $spells[$v2] = strtolower(substr($v1[$k2], -1));//json 数据的技能名称需要特殊处理
                                }

                            } else {
                                $spells[$v2] = importFilter($v1[$k2]);
                            }*/
                            //技能根据名称匹配
                            $spells[$v2] = importFilter($v1[$k2]);
                        }
                        //过滤技能
                        /*if(in_array($spells['spellKey'],array('w','q','e','r'))){
                            $data['spells'][] = $spells;
                        }*/
                        $data['spells'][] = $spells;
                    }

                }
                unset($spellsCate);
                unset($spells);
                unset($spells_key);
                break;
            case self::CATE_TMOBA_ITEM;
                $data['msg'] = '道具tmoba数据';
                $item = array();
                foreach ($json as $k => $v) {
                    //检测是否要过滤道具
                    $check = $this->checkItemName($v['name']);
                    if ($check === true) {
                        continue;
                    }
                    //过滤没有id的道具
                    if (empty($v['id'])) {
                        continue;
                    }
                    foreach ($category as $k1 => $v1) {
                        $item[$v1] = importFilter($v[$k1]);
                    }
                    if(!empty($item['itemId'])){
                        //道具图标处理
                        $item['iconPath'] = $this->itemIconPath.$item['itemId'].'.png';
                        //$item['iconPath'] = $this->itemIconPath.basename($v['iconPath']);
                        $data['data'][] = $item;
                    }
                }
                break;
            case self::CATE_JSON_ITEM;
                $data['msg'] = '道具json数据';
                $json = $json['data'];
                $item = array();
                foreach ($json as $k => $v) {
                    //检测是否要过滤道具
                    $check = $this->checkItemName($v['name']);
                    if ($check === true) {
                        continue;
                    }
                    if(intval($k) === 0){
                        continue;
                    }
                    //道具id特殊处理
                    $item['itemId'] = $k;
                    foreach ($category as $k1 => $v1) {
                        if (is_array($v1)) {
                            foreach ($v1 as $k2 => $v2) {
                                $item[$v2] = importFilter($v[$k1][$k2]);
                            }
                        } else {
                            $item[$v1] = importFilter($v[$k1]);
                        }
                    }
                    if(!empty($item['itemId'])){
                        $data['data'][] = $item;
                    }
                }
                break;
            case self::CATE_TMOBA_SKINS:
                $data['msg'] = '皮肤tmoba数据';
                //返回 皮肤数据 及炫彩皮肤数组
                $skins = array();
                $data['chromas'] = array();//炫彩皮肤
                foreach ($json as $k => $v) {
                    foreach ($category as $k1 => $v1) {
                        if ($k1 == 'id') {
                            //预存皮肤id
                            $skinId = $v[$k1];
                            $skins[$v1] = $v[$k1];
                        } elseif ($k1 == 'emblems') {
                            //皮肤标记
                            foreach ($v1 as $k2 => $v2) {
                                if (is_array($v[$k1])) {
                                    $emblems = array();
                                    foreach ($v[$k1] as $k3 => $v3) {
                                        $emblems[] = importFilter($v3[$k2]);
                                    }
                                    $skins[$v2] = implode(',', $emblems);//皮肤标记

                                } else {
                                    $skins[$v2] = '';//皮肤标记
                                }
                            }
                        } elseif ($k1 == 'chromas') {
                            //炫彩皮肤数据处理
                            if (is_array($v[$k1])) {
                                foreach ($v[$k1] as $k3 => $v3) {
                                    $chromas = array();//炫彩皮肤
                                    foreach ($v1 as $k2 => $v2) {
                                        $chromas[$v2] = importFilter($v3[$k2]);
                                    }
                                    $chromas['chromasBelongId'] = $skinId;

                                    $chromas['chromas'] = 1;
                                    $chromas['mainImg'] = $this->skinMainImg.'big'.$chromas['skinId'].'.jpg';
                                    $chromas['iconImg'] = $this->skinIconImg.'small'.$chromas['skinId'].'.jpg';
                                    $chromas['loadingImg'] = $this->skinLoadingImg.$chromas['skinId'].'.jpg';
                                    $chromas['videoImg'] = $this->skinVideoImg.'sp'.$chromas['skinId'].'.jpg';
                                    $chromas['sourceImg'] = $this->skinSourceImg.'guide'.$chromas['skinId'].'.jpg';

                                    $data['chromas'][] = $chromas;
                                }
                            } else {
                                $skins['chromasBelongId'] = 0;
                            }
                        } else {
                            $skins[$v1] = importFilter($v[$k1]);
                        }
                    }
                    $skins['chromas'] = 0;
                    $skins['mainImg'] = $this->skinMainImg.'big'.$skins['skinId'].'.jpg';
                    $skins['iconImg'] = $this->skinIconImg.'small'.$skins['skinId'].'.jpg';
                    $skins['loadingImg'] = $this->skinLoadingImg.$skins['skinId'].'.jpg';
                    $skins['videoImg'] = $this->skinVideoImg.'sp'.$skins['skinId'].'.jpg';
                    $skins['sourceImg'] = $this->skinSourceImg.'guide'.$skins['skinId'].'.jpg';
                    //判断皮肤 是base 还是common
                    if(empty($skins['emblemsName']) && intval($skins['isBase']) === 1){
                        $skins['emblemsName'] = 'base';
                    }elseif (empty($skins['emblemsName']) && intval($skins['isBase']) === 0){
                        $skins['emblemsName'] = 'common';
                    }
                    unset($skinId);
                    $data['data'][] = $skins;
                }
                break;
            default:
                recordAMSLog(__FILE__ . "," . __LINE__ . ",文件暂不支持");
                $res['code'] = 404;
                $res['msg'] = "文件暂不支持";
                return $res;
                break;
        }
        return $data;
    }

    /**
     * 获取最近三个版本的数据
     * @return mixed
     */
    public function getDataByDb()
    {
        if ($this->type != self::TYPE_DB) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",该方法仅获取数据库中最近三个版本的数据");
            $res['code'] = 404;
            $res['msg'] = "该方法仅获取数据库中最近三个版本的数据";
            return $res;
        }
        return $this->json;
    }

    /**
     * 返回数据变化的字段
     * 字段规则 原来key + IsChange  含义解释 1：变化 0：没变化
     * @param $data
     * @return mixed
     */
    public function getChangeByDb($data)
    {
        if(empty($data)){
            return $data;
        }
        $json = $this->json;
        $noCompareKey = $this->noCompareKey;

        $compareData = array();
        foreach ($json as $k => $v){
            if(!in_array($k,$noCompareKey)){
                $compareData[$k][] = str_replace(array("\r","\n","<br>","<br/>","<br />"),'',$v);
            }
        }
        foreach ($data as $k => $v){
            if(!in_array($k,$noCompareKey)){
                //比较版本数据
                $compareData[$k][] = str_replace(array("\r","\n","<br>","<br/>","<br />"),'',$v);
                $diff_count = count(array_unique($compareData[$k]));
                if($diff_count>1){
                    $data[$k."IsChange"] = 1;//数据较最新的版本
                }else{
                    $data[$k."IsChange"] = 0;
                }
            }
        }
        return $data;
    }

    public function getIsChangeByDb($data)
    {
        if(empty($data)){
            recordAMSLog(__FILE__ . "," . __LINE__ . ",数据为空");
            $res['code'] = 404;
            $res['msg'] = "数据为空";
            return $res;
        }
        $json = $this->json;
        $noCompareKey = $this->noCompareKey;
        $compareData = array();
        foreach ($json as $k => $v){
            if(!in_array($k,$noCompareKey)){
                $compareData[$k][] = str_replace(array("\r","\n","<br>","<br/>","<br />"),'',$v);
            }
        }
        foreach ($data as $k => $v){
            if(!in_array($k,$noCompareKey)){
                //比较版本数据
                $compareData[$k][] = str_replace(array("\r","\n","<br>","<br/>","<br />"),'',$v);
                $diff_count = count(array_unique($compareData[$k]));
                if($diff_count>1){
                    $res['code'] = 0;
                    $res['isChange'] = 1;
                    $res['msg'] = $k."发生变化";
                    return $res;
                }
            }
        }
        $res['code'] = 0;
        $res['isChange'] = 0;
        $res['msg'] = "无变化";
        return $res;
    }

    /**
     * 去除写数据库时新增的转义符再比较
     * @param $value
     * @return string
     */
    public function removeStripslashes($value){
        return stripslashes($value);
    }

    /**
     * 通过道具名称判断道具是否需要过滤
     * @param $name
     * @return bool
     */
    public function checkItemName($name)
    {
        $db = Lib\Db\DbModel::init();
        $find = $db->table('tbconfig')->where(['alias'=>'itemRemove'])->find('value');
        if(empty($find)){
            //不需要过滤
            return false;
        }
        $find['value'] = str_replace('，',',',$find['value']);
        $itemRemove = explode(',',$find['value']);

        if (empty($itemRemove)) {
            //不需要过滤
            return false;
        }
        foreach ($itemRemove as $v) {
            if (strpos($name, $v) !== false) {
                //需要过滤
                return true;
            }
        }
        //不需要过滤
        return false;
    }

    /**
     * 处理二维数字 将数据的位置字段提取成数组的key
     * @param $data
     * @param $type 要处理的数据类型
     */
    public function updateDataKey($data, $type = self::CATE_JSON_SPELL)
    {
        if (empty($data)) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",要处理的数据不能为空");
            return false;
        }
        if (!is_array($data[0])) {
            recordAMSLog(__FILE__ . "," . __LINE__ . ",该方法只处理多维数组");
            return false;
        }
        $new_data = array();
        switch ($type) {
            case self::CATE_TMOBA_SPELL:
            case self::CATE_JSON_SPELL:
                //处理技能数组
                foreach ($data as $k => $v) {
                    foreach ($v as $k1 => $v1) {
                        if ($k1 == 'spellKey') {
                            $new_data[$v1] = $v;
                        }
                    }
                }
                return $new_data;
                break;
            case self::CATE_TMOBA_SKINS:
                //处理皮肤数组
                foreach ($data as $k => $v) {
                    foreach ($v as $k1 => $v1) {
                        if ($k1 == 'skinId') {
                            $new_data[$v1] = $v;
                        }
                    }
                }
                return $new_data;
                break;
            case self::CATE_TMOBA_ITEM:
            case self::CATE_JSON_ITEM:
                //处理道具数组
                foreach ($data as $k => $v) {
                    foreach ($v as $k1 => $v1) {
                        if ($k1 == 'itemId') {
                            $new_data[$v1] = $v;
                        }
                    }
                }
                return $new_data;
                break;
            default:
                recordAMSLog(__FILE__ . "," . __LINE__ . ",暂不支持的类型", var_export($data, true));
                return $data;
                break;
        }

    }


}